home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / System / lpDaemon SRC / lpr Sources / LPR.C next >
Encoding:
C/C++ Source or Header  |  1993-03-30  |  6.5 KB  |  281 lines  |  [TEXT/KAHL]

  1. /************************************************************************
  2.  *                                                                        *
  3.  *    LPR.c                                                                *
  4.  *                                                                        *
  5.  *  Line Printer Daemon using TCP/IP printer protocol                    *
  6.  *                                                                        *
  7.  *              -------------- The lpd routines --------------            *
  8.  *                                                                        *
  9.  *  Written by Casper Boon, November, 1992.                                *
  10.  *                                                                        *
  11.  *    © 1992 Murdoch University.                                            *
  12.  *                                                                        *
  13.  ************************************************************************/
  14.  
  15. #include "LPR.H"
  16. #include "TCPStream.H"
  17. #include "BackGrounder.h"
  18. #include "lprProtos.h"
  19.  
  20.  
  21. static integer SendString(integer crefnum, StringPtr s);
  22. static integer GetResponse(integer crefnum, Byte which);
  23. static integer SendFile(integer fRef, StringPtr header, Handle ctl, Boolean text);
  24. static void clt_add(char *fmt, ...);
  25.  
  26.  
  27. static integer job_file = 0, cRef = 0;
  28. static Handle ctlFile = NIL;
  29. extern integer job_number;
  30. static char    host[256];
  31. static Byte    owner[64];
  32. static char rbuff[4098];
  33.  
  34. /************************************************************************
  35.  ************************************************************************/
  36. integer LPR(StringPtr fname, integer vRef, Boolean text_only)
  37. {
  38.     Str255    header, jobfName;
  39.     integer    fRef, res;
  40.     LongInt    file_size;
  41.  
  42.     psprintf(header, "Sending %p", fname);
  43.     LPR_Banner_Mess(header);
  44.  
  45.     if ( FSOpenRO(fname, vRef, &fRef) )    /* error opening file */
  46.         return -1;
  47.  
  48.     GetEOF(fRef, &file_size);
  49.  
  50.     psprintf(jobfName, "df%c%03d%p", 'A' + job_file++, job_number, my_host);
  51.     psprintf(header, "\3%ld %p\012", file_size, jobfName);
  52.  
  53.     if (!text_only)
  54.         clt_add("l%p\012", jobfName);
  55.     else
  56.         clt_add("f%p\012", jobfName);
  57.     clt_add("U%p\012", jobfName);
  58.     clt_add("N%p\012", fname);
  59.  
  60.     res = SendFile(fRef, header, NIL, text_only);
  61.  
  62.     FSClose(fRef);
  63.  
  64.     return res;
  65. }
  66.  
  67. /************************************************************************
  68.  ************************************************************************/
  69. integer SendCtlFile()
  70. {
  71.     Str255    header;
  72.  
  73.     LPR_Banner_Mess("\pSending control file");
  74.  
  75.     psprintf(header, "\2%ld cfA%03d\012", GetHandleSize(ctlFile), job_number);
  76.     return SendFile(0, header, ctlFile, TRUE);
  77. }
  78.  
  79. /************************************************************************
  80.  ************************************************************************/
  81. static integer SendFile(integer fRef, StringPtr header, Handle ctl, Boolean text)
  82. {
  83.     LongInt count = 4096, size, done = 0;
  84.     integer    state, i;
  85.     char    *s;
  86.  
  87.     if ( !SendString(cRef, header) )
  88.         return -1;
  89.  
  90.     if ( !GetResponse(cRef, 0) )
  91.         return -1;
  92.  
  93.     LPR_Banner_Mess("\pSending File");
  94.  
  95.     if (ctl)
  96.         {
  97.         count = GetHandleSize(ctl);
  98.  
  99.         if (count > 0)
  100.             {
  101.             HLock(ctl);
  102.  
  103.             for (i = 0, s = (char*)*ctl; i < count; i++, s++)
  104.                 if (*s == '\015') *s = '\012';
  105.  
  106.             if ( TCPSWrite(cRef, *ctl, count, &state) == noErr )
  107.                 while (state > 0) { DoIdles(&state); LPR_Banner_Spin(NIL); }
  108.  
  109.             HUnlock(ctl);
  110.  
  111.             if (state < 0) return -1;
  112.             }
  113.         done = count;
  114.         }
  115.     else
  116.         {
  117.         GetEOF(fRef, &size);
  118.         LPR_Banner_PCent(done, size);
  119.  
  120.         while ( !FSRead(fRef, &count, rbuff) || count)
  121.             {
  122.             if (text)
  123.                 {
  124.                 for (i = 0, s = rbuff; i < count; i++, s++)
  125.                     if (*s == '\015') *s = '\012';
  126.                 }
  127.             if ( TCPSWrite(cRef, rbuff, count, &state) == noErr )
  128.                 while (state > 0) DoIdles(&state);
  129.  
  130.             if (state < 0) return -1;
  131.  
  132.             done += count;
  133.             LPR_Banner_PCent(done, size);
  134.  
  135.             count = 4096;
  136.             }
  137.         }
  138.  
  139.     if ( TCPSWrite(cRef, "\0\0", 1, &state) == noErr )
  140.         while (state > 0) DoIdles(&state);
  141.  
  142.     if ( !GetResponse(cRef, 0) ) return -1;
  143.  
  144.     return 0;
  145. }
  146.  
  147. /********************************************************************
  148.  *                 Sends a string to the remote host.                    *
  149.  ********************************************************************/
  150. static integer SendString(integer cRef, StringPtr s)
  151. {
  152.     Word    slen;
  153.     integer state;
  154.  
  155.     if ( !(slen = *s++) ) return 1;
  156.  
  157.     if ( TCPSWrite(cRef, (Ptr)s, slen, &state) == noErr )
  158.         while (state > 0) { DoIdles(&state); LPR_Banner_Spin("\p"); }
  159.     else
  160.         return 0;
  161.  
  162.     if (state < 0)
  163.         return 0;    /* write failed */
  164.  
  165.     return 1;
  166. }
  167.  
  168. /********************************************************************/
  169. /*                 Get a response from the remote host.                */
  170. /********************************************************************/
  171. static integer GetResponse(integer cRef, Byte which)
  172. {
  173.     integer    state, size, eof;
  174.     Byte    buff[256], *s=buff;
  175.  
  176.     size = 256;
  177.  
  178.     if ( TCPSRead(cRef, (Ptr)buff, &size, &eof, &state) == noErr )
  179.         while (state > 0) { DoIdles(&state); LPR_Banner_Spin("\p"); }
  180.  
  181.     if (state < 0)
  182.         return 0;    /* read failed */
  183.  
  184.     if (buff[0] != which)
  185.         {
  186.         if (size > 1)
  187.             {
  188.             buff[0] = size - 1;
  189.             ParamText(buff, (StringPtr)"", (StringPtr)"", (StringPtr)"");
  190.             Alert(256, NIL);
  191.             }
  192.         return 0;
  193.         }
  194.  
  195.     return 1;
  196. }
  197.  
  198.  
  199. /************************************************************************
  200.  ************************************************************************/
  201. integer StartJob(StringPtr fname)
  202. {
  203.     integer    state = 0;
  204.     Str255    buffer;
  205.  
  206.     ctlFile = NewHandle(0);
  207.  
  208.     if (InitTCPS())
  209.         AlertUser(eInitTCP);
  210.  
  211.     BlockMove(my_user, owner, my_user[0]+1);
  212.     sprintf(host, "%p", prt_server);
  213.  
  214.     clt_add("H%p\012", my_host);
  215.     clt_add("P%p\012", owner);
  216.     clt_add("J%p\012", fname);
  217.     clt_add("C%p\012", my_host);
  218.     clt_add("L%p\012", owner);
  219.  
  220.     psprintf(buffer, "Connecting to %p", prt_server);
  221.     LPR_Banner_Up();
  222.     LPR_Banner_Spin(buffer);
  223.  
  224.     if ( TCPSOpen(&cRef, host, 721, LPD_PORT, FALSE, &state) != noErr )
  225.         return -1;    /* it failed */
  226.  
  227.     while (state > 0) { DoIdles(&state); LPR_Banner_Spin(NIL); }
  228.  
  229.     if (state < 0)
  230.         {
  231.         if ( TCPSClose(cRef, &state) == noErr )
  232.             while (state > 0) DoIdles(&state);
  233.         return -1;    /* couldn't open */
  234.         }
  235.  
  236.     psprintf(buffer, "\2%p\012", prt_name);
  237.     if ( !SendString(cRef, buffer) )    /* start job */
  238.         return -1;            /* failed ! */
  239.  
  240.     if ( !GetResponse(cRef, 0) )
  241.         return -1;
  242.  
  243.     return 0;
  244. }
  245.  
  246. /************************************************************************
  247.  ************************************************************************/
  248. integer EndJob()
  249. {
  250.     integer    state = 0;
  251.  
  252.     if ( TCPSClose(cRef, &state) == noErr )
  253.         while (state > 0) DoIdles(&state);
  254.  
  255.     ExitTCPS();
  256. }
  257.  
  258.  
  259. #include <stdarg.h>
  260. integer strlen(char*);
  261.  
  262. /************************************************************************
  263.  ************************************************************************/
  264. static void clt_add(char *fmt, ...)
  265. {
  266.     char    buff[256];
  267.     LongInt    len = GetHandleSize(ctlFile), slen;
  268.     va_list    arglist;
  269.  
  270.     va_start(arglist, fmt);
  271.     vsprintf(buff, fmt, arglist);
  272.     va_end(arglist);
  273.  
  274.     slen = strlen(buff);
  275.  
  276.     SetHandleSize(ctlFile, len+slen);
  277.     HLock(ctlFile);
  278.     BlockMove(buff, &(*ctlFile)[len], slen);
  279.     HUnlock(ctlFile); 
  280. }
  281.